custom routes map
tip
- router
- index.jsx
- routers.js
- subRouters.js
- components
- ...
router/routers.js
import { lazy } from "react"
import { Navigate } from "react-router-dom"
import From from "../from"
import subRouters from "./subRouters"
const config = [
{
name: "index",
path: "/",
// Navigate会直接被执行,所以要返回一个函数
component: () => {
return <Navigate to="/from" />
}
},
{
name: "from",
path: "/from",
component: From
},
{
name: "to",
path: "/to",
// 延迟加载
component: lazy(() => import("../to")),
// 导入子路由
children: subRouters
},
{
name: "complex",
path: "/to/:param0/:param1?",
component: lazy(() => import("../to"))
}
]
export default config
router/subRouters.js
import { lazy } from "react"
const subRouters = [
{
name: "to_0",
path: "/to/to_0",
// 自定义打包名称
// component: lazy(() =>import(/* webpackChunkName:"Jonathan-A" */ "../to0"))
component: lazy(() => import("../to0"))
},
{
name: "to_1",
path: "/to/to_1",
component: lazy(() => import("../to1"))
}
]
export default subRouters
import { Suspense } from "react"
import {
Routes,
Route,
useLocation,
useSearchParams,
useParams,
useNavigate
} from "react-router-dom"
import routers from "./routers"
export default function AutoRoutes() {
/**
* 统一渲染的组件:在这里可以做一些事情下例如: 权限/登录态校验,传递路由信息的属性...J
*/
const Element = (props) => {
// 解构出需要渲染的组件
let { component: Component } = props
// 注入路由钩子函数
const location = useLocation(),
navigate = useNavigate(),
[usp] = useSearchParams(),
params = useParams()
return (
<Component
navigate={navigate}
usp={usp}
params={params}
location={location}
/>
)
}
/**
* 递归构建路由表
*
* @param {*} routers
* @returns
*/
const buildRoutes = (routers) => {
return routers.map((item, key) => {
let { path, children = [] } = item
return (
// 将router map中的参数全部传入Element中
<Route key={key} path={path} element={<Element {...item} />}>
{buildRoutes(children)}
</Route>
)
})
}
return (
<Suspense>
<Routes>{buildRoutes(routers)}</Routes>
</Suspense>
)
}
/**
* 在react-router-dom v6版本中,路由全部只支持hooks方式获取,导致classComponent无法获取相关路由对象
* 在V5中可以使用withRouter,但在V6中没有,所以自定义一个高阶函数
*/
export const withRouter = (Component) => {
return function HOC(props) {
// 注入路由钩子函数
const location = useLocation(),
navigate = useNavigate(),
[usp] = useSearchParams(),
params = useParams()
return (
<Component
{...props}
navigate={navigate}
usp={usp}
params={params}
location={location}
/>
)
}
}
组件中获取路由相关对象
import { Link, Outlet } from "react-router-dom"
// 这里直接可以从注入的属性中获取路由相关hooks
export default function To({ location, usp, params }) {
let param0, param1
// 2.获取url参数-通过useSearchParams
if (usp) {
param0 = usp.get("param0")
param1 = usp.get("param1")
}
// 3.获取路由地址参数
if (params) {
param0 = params.param0
param1 = params.param1
}
// 4.获取hide方式参数
const { state } = location
if (state) {
param0 = state.param0
param1 = state.param1
}
return (
<>
<h1>From Component</h1>
<div>param0={param0}</div>
<div>param1={param1}</div>
<br />
<div>
<Link to="/to/to_0">to 0</Link>
<Link to="/to/to_1">to 1</Link>
<Outlet />
</div>
</>
)
}